package com.wolfpire.proms.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.wolfpire.proms.dao.ProjectIndexDao;
import com.wolfpire.proms.model.ProjectIndex;
import com.wolfpire.system.common.Page;
import com.wolfpire.system.common.base.dao.impl.BaseHibernateDao;

@Repository("projectIndexDao")
public class ProjectIndexDaoImpl extends BaseHibernateDao<ProjectIndex, Long> implements ProjectIndexDao {

	@Override
	public Page<ProjectIndex> findProjectIndexs(Page<ProjectIndex> page, ProjectIndex filterProjectIndex) {
		Criterion[] criterions = createFilter(filterProjectIndex, null, true);
		int totalCount = this.findIntByCriteria(criterions);
		page.setTotalCount(totalCount);
		
		if (0 < totalCount) {
			Criteria c = createCriteria(criterions);
			c.addOrder(Order.asc("seq"));
			c.addOrder(Order.asc("id"));
			c = this.setPageParameter(c, page);
			@SuppressWarnings({ "unchecked" })
			List<ProjectIndex> result = c.list();
			page.setDataList(result);
		}
		return page;
	}

	private Criterion[] createFilter(ProjectIndex filterProjectIndex, String type, boolean cascadeParentId) {
		if (null == filterProjectIndex) {
			return null;
		}
		List<Criterion> criterions = new ArrayList<Criterion>();
		if (null != filterProjectIndex.getId()) {
			criterions.add(Restrictions.eq("id", filterProjectIndex.getId()));
		}
		if (!StringUtils.isBlank(filterProjectIndex.getName())) {
			criterions.add(Restrictions.like("name", filterProjectIndex.getName(), MatchMode.ANYWHERE));
		}
		if (null != filterProjectIndex.getParentId()) {
			if (cascadeParentId) {
				List<Long> ids = this.findAllIds(filterProjectIndex.getParentId());
//				ids.add(filterProjectIndex.getParentId());
				criterions.add(Restrictions.or(Restrictions.in("parentId", ids), Restrictions.eq("id", filterProjectIndex.getParentId())));
			} else {
				criterions.add(Restrictions.eq("parentId", filterProjectIndex.getParentId()));
			}
		} else {
			if ("tree".equals(type)) {
				criterions.add(Restrictions.isNull("parentId"));
			}
		}
		if (!StringUtils.isBlank(filterProjectIndex.getRemark())) {
			criterions.add(Restrictions.like("remark", filterProjectIndex.getRemark(), MatchMode.ANYWHERE));
		}
		if (null != filterProjectIndex.getDelFlag()) {
			criterions.add(Restrictions.eq("delFlag", filterProjectIndex.getDelFlag()));
		}
		return criterions.toArray(new Criterion[criterions.size()]);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ProjectIndex> list(ProjectIndex projectIndex) {
		Criteria c = createCriteria(createFilter(projectIndex, "tree", false));
		c.addOrder(Order.asc("seq"));
		c.addOrder(Order.asc("id"));
		return c.list();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public List<Long> findAllIds(Long id) {
		String querySql = " SELECT id FROM t_project_index WHERE FIND_IN_SET(id, queryChildrenProjectIndex(:projectIndexId)) ";
		List propertyValues = new ArrayList();
		List<String> propertyNames = new ArrayList<String>();
		propertyNames.add("projectIndexId");
		propertyValues.add(id);
		SQLQuery query = this.createSqlQuery(querySql, propertyNames, propertyValues);
//		query.addEntity(Long.class);
		List list = query.list();
		List<Long> rs = new ArrayList<Long>();
		if (CollectionUtils.isNotEmpty(list)) {
			for (Object o : list) {
				rs.add(new Long(o.toString()));
			}
		}
		return rs;
	}

}
